/**
 * 飞行漫游
 * @copyright 火星科技 mars3d.cn
 * @author 火星胡椒 2022-02-19
 */

import * as mars3d from "mars3d"
import * as kgUtil from "kml-geojson"
import * as api from "@mars/common/api"
import { readJSON } from "@mars/utils/file-util"
import { $message } from "@mars/components/mars-ui/index"
import { logInfo } from "@mars/utils/mars-util"

let map: mars3d.Map // 地图对象
export let graphicLayer: mars3d.layer.GraphicLayer

// 事件对象，用于抛出事件给vue
export const eventTarget = new mars3d.BaseClass()

// 初始化当前业务
export function onMounted(mapInstance: mars3d.Map): void {
  map = mapInstance // 记录map

  graphicLayer = new mars3d.layer.GraphicLayer({
    isAutoEditing: true // 是否自动激活编辑
  })
  map.addLayer(graphicLayer)

  const editUpdateFun = mars3d.Util.funDebounce(graphicLayer_editUpdate, 500)
  graphicLayer.on(
    [
      mars3d.EventType.drawCreated,
      mars3d.EventType.editStart,
      mars3d.EventType.editMovePoint,
      mars3d.EventType.editStyle,
      mars3d.EventType.editRemovePoint
    ],
    editUpdateFun
  )
  const removeFun = mars3d.Util.funDebounce(graphicLayer_remove, 500)
  graphicLayer.on(mars3d.EventType.removeGraphic, removeFun)

  // 加载历史数据
  getHistoricalRecordsList()
}

// 释放当前业务
export function onUnmounted(): void {
  if (historyId) {
    updateHistoryRecords()
  } else {
    historyId = addHistoricalRecords()
  }

  if (graphicLayer) {
    graphicLayer.destroy() // 销毁内部会释放所有事件及数据
    graphicLayer = null
  }

  eventTarget.off()
  map = null
}

// ******************** 事件 ********************
// 修改样式，修改点，删除点等操作去激活或更新面板
function graphicLayer_editUpdate(e) {
  logInfo("漫游进行了修改操作", e)
  eventTarget.fire("plot_graphicEditor", { graphicId: e.graphic.id, layerId: graphicLayer.id })
}

function graphicLayer_remove(e) {
  logInfo("漫游触发删除操作", e)
  eventTarget.fire("plot_graphicEditor", { disable: true })
}

// ******************** 漫游处理 ********************
/**
 * 通过id查找漫游路线，对其进行操作
 *
 * @export
 * @param {(string|number)} id 矢量id
 * @param {string} type 操作处理
 * @returns {void} 无
 */
export function handleRoamById(id: string | number, type: string) {
  const graphic = graphicLayer.getGraphicById(id)

  if (!graphic) {
    return null
  }

  if (graphic.isEditing) {
    graphic.stopEditing()
  }

  switch (type) {
    case "remove":
      graphicLayer.removeGraphic(graphic)
      eventTarget.fire("refreshFlyData", { id, key: "remove" })
      break
    case "getOptions": {
      // graphic转 json
      const json = graphic.toJSON()
      return json
    }

    default:
      break
  }
}

// 新增漫游路线
export async function addRouteLine() {
  const name = "路线" + mars3d.Util.formatDate(new Date(), "MMddHHmmss") // 时间

  const graphic = await graphicLayer.startDraw({
    name,
    type: "fixedRoute",
    // @ts-expect-error
    camera: {
      type: "gs",
      radius: 300
    },
    model: {
      url: "https://data.mars3d.cn/gltf/mars/man/walk.gltf",
      minimumPixelSize: 50
    },
    polyline: {
      width: 3,
      color: "#ffff00",
      showAll: true
    }
  })

  eventTarget.fire("refreshFlyData", { data: { name, key: graphic.id, id: graphic.id }, key: "add" })
}

// =======================文件保存与导入=============================

/**
 * 保存文件
 *
 * @export
 * @param {any[]} arrFlyTable 任意类型的数组
 * @returns {void} 无
 */
export function saveFile() {
  if (graphicLayer.length === 0) {
    $message("当前没有任何数据，无需保存！")
    return
  }
  const json = graphicLayer.toJSON()
  mars3d.Util.downloadFile("飞行漫游路线.json", JSON.stringify(json))
}

// 打开保存的文件
export async function impFile(file: any) {
  const fileName = file.name
  const fileType = fileName?.substring(fileName.lastIndexOf(".") + 1, fileName.length).toLowerCase()

  if (fileType === "json" || fileType === "geojson") {
    const jsonData: any = await readJSON(file)
    graphicLayer.loadJSON(jsonData, {
      flyTo: true,
      clear: true
    })

    eventTarget.fire("refreshFlyData", { data: jsonData.data ?? [], key: "new" })
  } else if (fileType === "kml") {
    const reader = new FileReader()
    reader.readAsText(file, "UTF-8")
    reader.onloadend = function (e) {
      const strkml = this.result
      kgUtil.toGeoJSON(strkml).then((geojson) => {
        logInfo("kml2geojson", geojson)

        eventTarget.fire("refreshFlyData", { data: geojson, key: "new" })
        graphicLayer.loadGeoJSON(geojson, { flyTo: true })
      })
    }
  } else if (fileType === "kmz") {
    // 加载input文件控件的二进制流
    kgUtil.toGeoJSON(file).then((geojson) => {
      logInfo("kmz2geojson", geojson)

      eventTarget.fire("refreshFlyData", { data: geojson, key: "new" })
      graphicLayer.loadGeoJSON(geojson, { flyTo: true })
    })
  } else {
    $message("暂不支持 " + fileType + " 文件类型的数据！")
  }
}
// 加载数据
function loadJSON(json: any, options: any) {
  graphicLayer.loadJSON(json, options)
}

// *************** 与后端接口操作 ***************
let historyId: any
const storageType = "mars_roamLine"

// 获取所有的历史数据
export async function getHistoricalRecordsList() {
  // const { code, data } = await api.getHistoricalRecordsList({ type: storageType })
  // if (code === 200 && data) {
  //   const item = data.find((it) => it.type === storageType)
  //   logInfo("获取到历史数据 mars_roamLine", data, item)

  //   if (!item) { return }
  //   historyId = item?.id ?? null
  //   if (item?.content) {
  //     const content = JSON.parse(item.content)
  //     logInfo("获取到历史数据 content", content)

  //     eventTarget.fire("refreshFlyData", { data: content.data, key: "new" })
  //     loadJSON(content, { clear: true, flyTo: true })
  //   }
  // }
}

// 添加历史数据
async function addHistoricalRecords() {
  // const json = graphicLayer.toJSON()

  // const { code, data } = await api.addHistoricalRecords({
  //   title: json.name,
  //   type: storageType,
  //   content: JSON.stringify(json)
  // })

  // if (code === 200 && data) {
  //   return data.id
  // }
}

// 更新历史数据
async function updateHistoryRecords() {
  // const json = graphicLayer.toJSON()
  // const { code } = await api.updateHistoryRecords({
  //   id: historyId,
  //   title: json.name,
  //   type: storageType,
  //   content: JSON.stringify(json)
  // })

  // if (code === 200) {
  //   logInfo("更新历史数据")
  // } else {
  //   logInfo("更新失败")
  // }
}

// 删除历史数据
async function deleteHistoricalRecordsById() {
  // const { code } = await api.deleteHistoricalRecordsById(historyId)

  // if (code === 200) {
  //   logInfo("删除历史数据")
  // } else {
  //   logInfo("删除失败")
  // }
}
